home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 April / EnigmA AMIGA RUN 17 (1997)(G.R. Edizioni)(IT)[!][issue 1997-04][EAR-CD].iso / EARCD / comm / bbs / citsrc6K05.lha / netrcv.c < prev    next >
C/C++ Source or Header  |  1996-09-23  |  22KB  |  910 lines

  1. /*
  2. *       netrcv.c
  3. *
  4. *      Networking functions for reception.
  5. */
  6. /*
  7. *       history
  8. *
  9. * 86Aug20 HAW  History not maintained due to space problems.
  10. */
  11. #include "ctdl.h"
  12. /*
  13. *       Contents
  14. *
  15. * called()    Handle being called.
  16. * rcvStuff()    Manage receiving stuff.
  17. * netPwd()    Check password.
  18. * doResults()   Post-process results.
  19. * getId()     Get nodeId and nodeName from caller.
  20. * getNextCommand()  Get next command.
  21. * grabCommand()   Extract network cmds from buffer.
  22. * reply()     Sends a reply to caller.
  23. * reqReversal()   Handle role reversal.
  24. * reqCheckMail()    Check incoming mail.
  25. * targetCheck()   Check for existence of recipients.
  26. * CheckRecipient()  work fn for above.
  27. * doNetRooms()    Manage integrating incoming messages.
  28. * IntegrateRoom()   work fn for above.
  29. * ReadNetRoomFile() work fn for above.
  30. * getMail()   Handle incoming mail.
  31. * reqSendFile()   Receive a sent file.
  32. * netFileReq()    Senda a requested file.
  33. * netRRReq()    Handle room sharing.
  34. * recNetMessages()  Receive net messages.
  35. * UpdateRecoveryFile()  Updates the network recovery file.
  36. *   RoomRoutable()    Is this room routable?
  37. * IsRoomRoutable()  Is this room routable?
  38. * netMultiSend()    Send multiple files.
  39. * RecoverNetwork()  Recover from network disaster.
  40. */
  41. extern char logNetResults;
  42. char        netDebug = FALSE;
  43. char    processMail;
  44. char    PosId;
  45. char    *AssignAddress = NULL;
  46. #define RECOVERABLE 1
  47. extern char   *SR_Sent;
  48. extern FILE   *netLog, *netMisc;
  49. extern AN_UNSIGNED      RecBuf[];
  50. extern int    counter;
  51. extern int    callSlot;
  52. extern char   checkNegMail;
  53. extern char   inReceive;
  54. extern label    normed, callerName, callerId;
  55. extern char   RouteMailForHere;
  56. extern char   *LOC_NET, *NON_LOC_NET;
  57. char    normId(), getNetMessage();
  58. char    callOut();
  59. AN_UNSIGNED      inp();
  60. char *netRoomTemplate = "room%d.$$$";
  61. char *SharingRefusal[] =
  62.   {
  63.   "'%s' does not exist",
  64.   "'%s' is not a networking room",
  65.   "'%s' is not networking with you",
  66.   "No can do for '%s'",
  67.  
  68.   };
  69. extern char  RecMassTransfer;
  70. extern CONFIG    cfg;   /* Lots an lots of variables    */
  71. extern logBuffer logBuf;  /* Person buffer    */
  72. extern logBuffer logTmp;  /* Person buffer    */
  73. extern aRoom     roomBuf; /* Room buffer    */
  74. extern rTable    *roomTab;
  75. extern MessageBuffer   msgBuf;
  76. extern NetBuffer netBuf;
  77. extern NetTable  *netTab;
  78. extern int       thisNet;
  79. extern char      onConsole;
  80. extern char      loggedIn;  /* Is we logged in?   */
  81. extern char      outFlag; /* Output flag    */
  82. extern char      haveCarrier; /* Do we still got carrier?     */
  83. extern char      modStat; /* Needed so we don't die       */
  84. extern char      WCError;
  85. extern int       thisRoom;
  86. extern int       thisLog;
  87. extern char  *APPEND_TEXT, *WRITE_TEXT, *READ_TEXT;
  88. extern char  *R_SH_MARK, *NON_LOC_NET, *LOC_NET;
  89. extern long char_in, char_out, start_time;
  90.  
  91. /*
  92. * called()
  93. *
  94. * We've been called, so let's handle it.
  95. */
  96. void called()
  97.   {
  98.   ITL_InitCall();   /* Initialize the ITL layer */
  99.   memset(SR_Sent, 0, SHARED_ROOMS);
  100.   inReceive = TRUE;
  101.   RecMassTransfer = FALSE;
  102.   SpecialMessage("Status:Net Carrier");
  103.   if( logNetResults || netDebug )splitF(netLog, "Carrier %s\n", Current_Time());
  104.   processMail = checkNegMail = FALSE;
  105.   if (!called_stabilize())
  106.     {
  107.     if (cfg.BoolFlags.debug)splitF(netLog," Not Stabilized...\n");
  108.     return ;
  109.  
  110.     };
  111.   if( logNetResults )splitF(netLog, "Stabilized\n");
  112.   SpecialMessage("Status:Net Session");
  113.   char_in = char_out = 0;
  114.   start_time = Set_Timer(0);       /* initialize time of day */
  115.   getId();
  116.   if (!haveCarrier) return;
  117.   rcvStuff(FALSE);
  118.   if ( logNetResults )splitF(netLog, "Finished with %s @%s\n",  callerName, Current_Time());
  119.   Compute_Data(callerName);
  120.   pause(20);
  121.   killConnection();
  122.   doResults();
  123.   if( logNetResults )splitF(netLog, "\n");
  124.   SpecialMessage("Status:Net Completed");
  125.  
  126.   }
  127. /*
  128. * rcvStuff()
  129. *
  130. * This function manages receiving stuff.
  131. */
  132. void rcvStuff(char reversed)
  133.   {
  134.   label     tempNm;
  135.   struct cmd_data cmds;
  136.   PosId = (callSlot == ERROR) ? FALSE : (netBuf.OurPwd[0] == 0 || (reversed && netBuf.nbflags.Stadel));
  137.   RouteMailForHere = FALSE;
  138.   do
  139.     {
  140.     getNextCommand(&cmds);
  141.     switch (cmds.command)
  142.       {
  143.       case HANGUP:          break;
  144.       case NORMAL_MAIL:    getMail();     break;
  145.       case A_FILE_REQ:
  146.       case R_FILE_REQ:     netFileReq(&cmds);   break;
  147.       case NET_ROOM:       netRRReq(&cmds, FALSE);  break;
  148.       case ROLE_REVERSAL:  reqReversal(reversed);   break;
  149.       case CHECK_MAIL:     reqCheckMail();    break;
  150.       case SEND_FILE:      reqSendFile(&cmds);    break;
  151.       case NET_ROUTE_ROOM: netRRReq(&cmds, TRUE);   break;
  152.       case SYS_NET_PWD:    netPwd(&cmds);     break;
  153.       case ITL_PROTOCOL:   ITL_rec_optimize(&cmds);       break;
  154.       case ITL_COMPACT:    ITL_RecCompact(&cmds);   break;
  155.       case ROUTE_MAIL:     netRouteMail(&cmds);   break;
  156.       case FAST_MSGS:  netFastTran(&cmds);    break;
  157.       default:
  158.       sprintf(tempNm, "'%d' unknown.", cmds.command);
  159.       reply(BAD, tempNm);   break;
  160.  
  161.       }
  162.  
  163.     }
  164.   while (gotCarrier() && cmds.command != HANGUP);
  165.  
  166.   }
  167. /*
  168. * netPwd()
  169. *
  170. * Check out the password sent to us, set flags appropriately.
  171. */
  172. void netPwd(struct cmd_data *cmds)
  173.   {
  174.   if (callSlot != ERROR)
  175.     {
  176.     PosId = !strCmpU(cmds->fields[0], netBuf.OurPwd);
  177.     if (!PosId)
  178.       {
  179.       if( logNetResults )splitF(netLog, "Bad pwd: -%s-\n", cmds->fields[0]);
  180.       sPrintf(msgBuf.mbtext, "%s sent bad password -%s-.",
  181.       callerName, cmds->fields[0]);
  182.       netResult(msgBuf.mbtext);
  183.  
  184.       }
  185.  
  186.     }
  187.   reply(GOOD, "");
  188.  
  189.   }
  190. /*
  191. * doResults()
  192. *
  193. * This function processes the results of receiving thingies and such.
  194. */
  195. void doResults()
  196.   {
  197.   extern SListBase DomainMap;
  198.   void HandleExistingDomain();
  199.   int i;
  200.   label temp;
  201.   extern int RMcount;
  202.   DisableModem(TRUE);
  203.   InitVortexing();    /* handles all mail for here */
  204.   if (processMail)
  205.     {
  206.     if (AddNetMsgs("tempmail.$$$", inMail, 2, MAILROOM, TRUE) == ERROR)
  207.     no_good("No mail file for %s?", TRUE);
  208.  
  209.     }
  210.   if (RouteMailForHere)
  211.     {
  212.     for (i = 0; ; i++)
  213.       {
  214.       sPrintf(temp, "rmail.%d", i);
  215.       if (AddNetMsgs(temp, inRouteMail, 2, MAILROOM, TRUE) == ERROR)
  216.       break;
  217.  
  218.       }
  219.     RMcount = 0;
  220.  
  221.     }
  222.   FinVortexing();   /* finish handling mail */
  223.   if (callSlot == ERROR)
  224.     {
  225.     /* If didn't know this node, don't      */
  226.     EnableModem(TRUE);
  227.     return ;  /* bother with anything else  */
  228.  
  229.     }
  230.   if (checkNegMail) readNegMail(TRUE);
  231.   ReadFastFiles();    /* messages transferred in one big arc */
  232.   doNetRooms();
  233.   AdjustRoute();
  234.   netBuf.nbLastConnect = CurAbsolute();
  235.   putNet(thisNet, &netBuf);
  236.   UpdVirtStuff(); /* Just in case. */
  237.   RunList(&DomainMap, HandleExistingDomain);
  238.   RationalizeDomains(); /* again just in case ... */
  239.   EnableModem(TRUE);
  240.  
  241.   }
  242. /*
  243. * getId()
  244. *
  245. * This gets nodeId and nodeName from caller.
  246. */
  247. void getId()
  248.   {
  249.   char *secRunner;
  250.   #ifdef NEED_THIS_DATA
  251.   SYS_FILE fn;
  252.   #endif
  253.   int i;
  254.   extern long byteRate;
  255.   extern char *APPEND_ANY;
  256.   if (!haveCarrier) return;
  257.   ITL_Receive(NULL, FALSE, TRUE, putFLChar, fclose);
  258.   if (!gotCarrier())
  259.     {
  260.     return ;
  261.  
  262.     }
  263.   strncpy(callerId, RecBuf, NAMESIZE - 1);
  264.   secRunner = RecBuf;
  265.   while (*secRunner != 0) secRunner++;
  266.   secRunner++;
  267.   strncpy(callerName, secRunner, NAMESIZE - 1);
  268.   normId(callerId, normed);
  269.   if (strLen(callerName) == 0 || strLen(callerId) == 0)
  270.     {
  271.     if( logNetResults )splitF(netLog, "getId invalid data, dropping connection.\n\n");
  272.     killConnection();
  273.     #ifdef NEED_THIS_DATA
  274.     makeSysName(fn, "getid.sys", &cfg.netArea);
  275.     if ((upfd = safeopen(fn, APPEND_ANY)) != NULL)
  276.       {
  277.       fwrite(RecBuf, SECTSIZE, 1, upfd);
  278.       fclose(upfd);
  279.  
  280.       }
  281.     #endif
  282.  
  283.     }
  284.   if ((callSlot = searchNet(normed, &netBuf)) == ERROR)
  285.     {
  286.     sPrintf(msgBuf.mbtext, "New caller: %s (%s)", callerName, callerId);
  287.     netResult(msgBuf.mbtext);
  288.  
  289.     }
  290.   else
  291.     {
  292.     for (i = 0; i < SHARED_ROOMS; i++)
  293.     resetNeedsProcessing(i);
  294.     putNet(callSlot, &netBuf);
  295.  
  296.     }
  297.   if( logNetResults)splitF(netLog, "%s (%s) @ %ld\n", callerName, callerId, byteRate * 10L);
  298.  
  299.   }
  300. /*
  301. * getNextCommand()
  302. *
  303. * This gets next command (facility request) from the caller.
  304. */
  305. void getNextCommand(struct cmd_data *cmds)
  306.   {
  307.   zero_struct(*cmds);
  308.   ITL_Receive(NULL, FALSE, TRUE, putFLChar, fclose);
  309.   if (!gotCarrier())
  310.     {
  311.     return ;
  312.  
  313.     }
  314.   grabCommand(cmds, RecBuf);
  315.   }
  316. /*
  317. * grabCommand()
  318. *
  319. * This pulls network cmds out of the specified buffer.
  320. */
  321. void grabCommand(struct cmd_data *cmds, char *sect)
  322.   {
  323.   int fcount = 0;
  324.   cmds->command = sect[0];
  325.   sect++;
  326.   while (sect[0] > 0 && fcount < 4)
  327.     {
  328.     strncpy(cmds->fields[fcount], sect, NAMESIZE - 1);
  329.     cmds->fields[fcount][NAMESIZE - 1] = 0;
  330.     fcount++;
  331.     while (*sect != 0) sect++;
  332.     sect++;
  333.  
  334.     }
  335.   }
  336. /*
  337. * reply()
  338. *
  339. * This sends a full reply to the caller's request.
  340. */
  341. void reply(char state, char *reason)
  342.   {
  343.   if (!ITL_Send(STARTUP))
  344.     {
  345.     no_good("Couldn't send reply to %s!", TRUE);
  346.     return;
  347.  
  348.     }
  349.   sendITLchar(state);
  350.   if (state == BAD)
  351.     {
  352.     mTrPrintf("%s", reason);
  353.     if (cfg.BoolFlags.debug) splitF(netLog, "Replying BAD: %s\n", reason);
  354.  
  355.     }
  356.   sendITLchar(0);
  357.   ITL_Send(FINISH);
  358.  
  359.   }
  360. /*
  361. * reqReversal()
  362. *
  363. * This handles the role reversal command.
  364. */
  365. void reqReversal(char reversed)
  366.   {
  367.   if ( netDebug ) splitF(netLog, "Role reversal\n");
  368.   if (reversed)
  369.     {
  370.     reply(BAD, "Synch error on Reversal!");
  371.     return ;
  372.  
  373.     }
  374.   reply(GOOD, "");
  375.   if (callSlot == ERROR)      /* Forces a "null" role reversal  */
  376.   zero_struct(netBuf.nbflags);
  377.   sendStuff(TRUE, PosId);
  378.  
  379.   }
  380. /*
  381. * reqCheckMail()
  382. *
  383. * This checks incoming mail and does negative acks where appropriate.
  384. */
  385. void reqCheckMail()
  386.   {
  387.   if( logNetResults && netDebug )splitF(netLog, "checking Mail\n");
  388.   if (!processMail)
  389.     {
  390.     reply(BAD, "No mail to check!");
  391.     return ;
  392.  
  393.     }
  394.   reply(GOOD, "");
  395.   if (ITL_Send(STARTUP))
  396.     {
  397.     AddNetMsgs("tempmail.$$$", targetCheck, FALSE, MAILROOM, TRUE);
  398.     sendITLchar(NO_ERROR);
  399.     ITL_Send(FINISH);
  400.  
  401.     }
  402.  
  403.   }
  404. /*
  405. * targetCheck()
  406. *
  407. * This checks for existence of recipients.
  408. */
  409. void targetCheck()
  410.   {
  411.   if (HasOverrides(&msgBuf))
  412.     {
  413.     RunList(&msgBuf.mbOverride, CheckRecipient);
  414.  
  415.     }
  416.   else
  417.     {
  418.     CheckRecipient(msgBuf.mbto);
  419.  
  420.     }
  421.  
  422.   }
  423. /*
  424. * CheckRecipient()
  425. *
  426. * This will check to see if the recipient exists.
  427. */
  428. void CheckRecipient(char *d)
  429.   {
  430.   char     sigChar;
  431.   if (!d[0])
  432.     {
  433.     sigChar = BAD_FORM;
  434.  
  435.     }
  436.   else if (strchr(d, '!') != NULL)
  437.   return ;  /* STadel routed mail - don't try to check it here */
  438.   else
  439.     {
  440.     if (PersonExists(d) != ERROR)
  441.     return ;
  442.     else
  443.     sigChar = NO_RECIPIENT;
  444.  
  445.     }
  446.   sendITLchar(sigChar);
  447.   mTrPrintf("%s", msgBuf.mbauth);
  448.   mTrPrintf("%s", d);
  449.   mTrPrintf("%s @ %s", msgBuf.mbdate, msgBuf.mbtime);
  450.  
  451.   }
  452. /*
  453. * doNetRooms()
  454. *
  455. * This function integrates temporary files containing incoming messages into
  456. * the data base.
  457. */
  458. void doNetRooms()
  459.   {
  460.   SYS_FILE fileNm;
  461.   int IntegrateRoom(SharedRoom *room, int system, int index, int roomslot,
  462.   void *d);
  463.   EachSharedRoom(thisNet, IntegrateRoom, NULL, NULL);
  464.   makeSysName(fileNm, RECOVERY_FILE, &cfg.netArea);
  465.   unlink(fileNm);
  466.  
  467.   }
  468. /*
  469. * IntegrateRoom()
  470. *
  471. * This function helps integrate incoming messages into a room.
  472. */
  473. int IntegrateRoom(SharedRoom *room, int system, int index, int roomslot,
  474. void *d)
  475.   {
  476.   if (chkNeedsProcessing(index))
  477.     {
  478.     ReadNetRoomFile(index, NULL);
  479.     resetNeedsProcessing(index);
  480.  
  481.     }
  482.   if (SR_Sent[index] == 1)
  483.   netBuf.netRooms[index].lastMess =  roomTab[roomslot].rtlastMessage;
  484.   return TRUE;
  485.  
  486.   }
  487. /*
  488. * ReadNetRoomFile()
  489. *
  490. * This function reads in a file of messages received on net.
  491. * NB: the passed parameter is the index into the netBuf.netRooms
  492. * pseudo-array, not the number of the room itself.  See the code.
  493. */
  494. void ReadNetRoomFile(int rover, char *fn)
  495.   {
  496.   label temp2;
  497.   if (cfg.BoolFlags.debug)splitF(netLog," ReadNetRoomFile(Rover:%d, fn:%s)\n",rover,(fn== NULL) ? "NULL":fn);
  498.   if (fn == NULL) sPrintf(temp2, netRoomTemplate, netRoomSlot(rover));
  499.   getRoom(netRoomSlot(rover));
  500.   if (roomBuf.rbShareType != PEON &&
  501.   GetMode(netBuf.netRooms[rover].mode) != PEON)
  502.   AssignAddress = NON_LOC_NET;
  503.   else
  504.   AssignAddress = LOC_NET;
  505.   InitVortexing();
  506.   AddNetMsgs((fn == NULL) ? temp2 : fn, inMail, TRUE, netRoomSlot(rover),
  507.   (fn == NULL));
  508.   FinVortexing();
  509.   AssignAddress = NULL;
  510.  
  511.   }
  512. /*
  513. * getMail()
  514. *
  515. * This function Grabs mail from caller.
  516. */
  517. void getMail()
  518.   {
  519.   SYS_FILE tempNm;
  520.   if( netDebug && logNetResults) splitF(netLog, "Receiving Mail\n");
  521.   makeSysName(tempNm, "tempmail.$$$", &cfg.netArea);
  522.   if (ITL_StartRecMsgs(tempNm, TRUE, TRUE, NULL) == ITL_SUCCESS)
  523.     {
  524.     processMail = TRUE;
  525.  
  526.     }
  527.  
  528.   }
  529. /*
  530. * reqSendFile()
  531. *
  532. * This function handles receiving a sent file.  Note that it handles file
  533. * redirection.
  534. */
  535. void reqSendFile(struct cmd_data *cmds)
  536.   {
  537.   long  proposed;
  538.   int count;
  539.   char work[100], work1[100], *Dir;
  540.   extern char *READ_ANY, *WRITE_ANY;
  541.   static char *Reject = "File %s from %s rejected because %s.";
  542.   /* don't accept files from rogues */
  543.   if (!PosId)
  544.     {
  545.     reply(BAD, "No room for file.");
  546.     return;
  547.  
  548.     }
  549.   /* handle incoming file redirection */
  550.   if ((Dir = RedirectFile(cmds->fields[0], netBuf.netName)) != NULL ||
  551.   (Dir = RedirectFile(cmds->fields[0], netBuf.nbShort)) != NULL)
  552.     {
  553.     RedirectName(work1, Dir, "mm12"); /* temp file name */
  554.     unlink(work1);  /* kill any prior backups (shouldn't be any ...) */
  555.     RedirectName(work, Dir, cmds->fields[0]);
  556.     if (access(work, 0) == 0)
  557.     rename(work, work1);
  558.  
  559.     }
  560.   else if (netSetNewArea(&cfg.receptArea))
  561.     {
  562.     proposed = atol(cmds->fields[2]);
  563.     if (sysRoomLeft() < proposed ||
  564.     proposed > ((long) cfg.maxFileSize) * 1024l)
  565.       {
  566.       reply(BAD, "No room for file.");
  567.       sPrintf(msgBuf.mbtext, Reject, cmds->fields[0], callerName,
  568.       proposed > ((long) cfg.maxFileSize) * 1024l ?
  569.       "the file was larger than #MAX_NET_FILE" :
  570.       "there was not enough room left in reception directory");
  571.       netResult(msgBuf.mbtext);
  572.       homeSpace();
  573.       return;
  574.  
  575.       }
  576.     count = 0;
  577.     strCpy(work, cmds->fields[0]);
  578.     while (access(work, 0) != -1)
  579.       {
  580.       sPrintf(work, "a.%d", count++);
  581.  
  582.       }
  583.  
  584.     }
  585.   else
  586.     {
  587.     reply(BAD, "System error");
  588.     return ;
  589.  
  590.     }
  591.   reply(GOOD, NULL);
  592.   if( logNetResults )splitF(netLog, "File Reception: %s\n", cmds->fields[0]);
  593.   ITL_Receive(work, FALSE, TRUE, putFLChar, fclose);
  594.   homeSpace();
  595.   if (haveCarrier)
  596.     {
  597.     if (strCmp(work, cmds->fields[0]) == SAMESTRING || Dir != NULL)
  598.     sPrintf(msgBuf.mbtext, "%s received from %s.", cmds->fields[0],
  599.     callerName);
  600.     else
  601.     sPrintf(msgBuf.mbtext, "%s (saved as %s) received from %s.",
  602.     cmds->fields[0], work, callerName);
  603.     netResult(msgBuf.mbtext);
  604.     if (Dir != NULL)  /* kill temporary bkp of redirected file */
  605.     unlink(work1);
  606.  
  607.     }
  608.   else if (Dir != NULL) /* failed transfer of redirected file */
  609.   rename(work1, work);
  610.  
  611.   }
  612. /*
  613. * netFileReq()
  614. *
  615. * This will handle requests for file transfers.
  616. */
  617. void netFileReq(struct cmd_data *cmds)
  618.   {
  619.   int  roomSlot;
  620.   extern char *READ_ANY;
  621.   if( logNetResults)splitF(netLog, "File request: %s in %s\n", cmds->fields[1],
  622.   cmds->fields[0]);
  623.   /* allow disabling this feature on a system by system basis */
  624.   if (PosId && netBuf.nbflags.NoDL)
  625.     {
  626.     reply(BAD, "Downloading disabled.");
  627.     return;
  628.  
  629.     }
  630.   if ((roomSlot = roomExists(cmds->fields[0])) == ERROR   ||
  631.   !roomTab[roomSlot].rtflags.ISDIR  ||
  632.   roomTab[roomSlot].rtflags.NO_NET_DOWNLOAD ||
  633.   !roomTab[roomSlot].rtflags.DOWNLOAD)
  634.     {
  635.     sPrintf(msgBuf.mbtext, "Room %s does not exist.", cmds->fields[0]);
  636.     reply(BAD, msgBuf.mbtext);
  637.     return;
  638.  
  639.     }
  640.   getRoom(roomSlot);
  641.   if (!setSpace(&roomBuf))
  642.     {
  643.     reply(BAD, "Directory error");
  644.     return;
  645.  
  646.     }
  647.   if (cmds->command == A_FILE_REQ)
  648.     {
  649.     reply(GOOD, "");
  650.     sPrintf(msgBuf.mbtext, "Following files sent to %s from %s: ",
  651.     callerName, roomBuf.rbname);
  652.     wildCard(netMultiSend, cmds->fields[1], FALSE, "", FALSE);
  653.     if (ITL_Send(STARTUP))
  654.       {
  655.       mTrPrintf("");
  656.       ITL_Send(FINISH);
  657.  
  658.       }
  659.  
  660.     }
  661.   else
  662.     {
  663.     if (access(cmds->fields[1], 4) == -1)
  664.       {
  665.       sPrintf(msgBuf.mbtext, "There is no '%s' in %s.", cmds->fields[1],
  666.       cmds->fields[0]);
  667.       reply(BAD, msgBuf.mbtext);
  668.       homeSpace();
  669.       return;
  670.  
  671.       }
  672.     reply(GOOD, "");
  673.     SendHostFile(cmds->fields[1]);
  674.     sPrintf(msgBuf.mbtext,
  675.     "%s downloaded from %s by %s.",
  676.     cmds->fields[1], formRoom(thisRoom, FALSE, FALSE), callerName);
  677.  
  678.     }
  679.   homeSpace();
  680.   netResult(msgBuf.mbtext);
  681.  
  682.   }
  683. /*
  684. * netRRReq()
  685. *
  686. * This function handles room sharing.  If SendBack is TRUE then this is a
  687. * room routing (LD) request and requires we send the room's current contents
  688. * back.
  689. */
  690. void netRRReq(struct cmd_data *cmds, char SendBack)
  691.   {
  692.   RoomSearch arg;
  693.   char reason[50];
  694.   strCpy(arg.Room, cmds->fields[0]);
  695.   if (!RoomRoutable(&arg))
  696.     {
  697.     sPrintf(reason, SharingRefusal[arg.reason], cmds->fields[0]);
  698.     if( logNetResults )splitF(netLog, "Refusing to share %s (%s)\n", cmds->fields[0], reason);
  699.     reply(BAD, reason);
  700.     return;
  701.  
  702.     }
  703.   if (!arg.virtual)
  704.     {
  705.     getRoom(arg.room);
  706.     recNetMessages(arg.index, arg.Room, arg.room, TRUE);
  707.     if (SendBack)
  708.     findAndSend(ERROR, R_SH_MARK, LOC_NET,
  709.     roomBuf.rbShareType == BACKBONE ? NON_LOC_NET : NULL, arg.index,
  710.     RoomSend, roomBuf.rbname, RoomReceive);
  711.  
  712.     }
  713.   else
  714.     {
  715.     RecVirtualRoom(arg.index, TRUE);
  716.     if (SendBack)
  717.     findAndSend(ERROR, NULL, NULL, NULL, arg.index, SendVirtual,
  718.     arg.Room, RecVirtualRoom);
  719.  
  720.     }
  721.  
  722.   }
  723. /*
  724. * recNetMessages()
  725. *
  726. * This function receives net messages.  This is not the same as processing
  727. * them.
  728. */
  729. void recNetMessages(int arraySlot, char *name, int slot, char ReplyFirst)
  730.   {
  731.   SYS_FILE fileNm, temp;
  732.   char reason[60];
  733.   if( netDebug )splitF(netLog, "Receiving %s\n", name);
  734.   sPrintf(temp, netRoomTemplate, slot);
  735.   makeSysName(fileNm, temp, &cfg.netArea);
  736.   switch (ITL_StartRecMsgs(fileNm, ReplyFirst, TRUE, NULL))
  737.     {
  738.     case ITL_SUCCESS:
  739.     setNeedsProcessing(arraySlot);
  740.     UpdateRecoveryFile(name);
  741.     break;
  742.     case ITL_NO_OPEN:
  743.     sPrintf(reason, "Internal error for %s", name);
  744.     reply(BAD, reason);
  745.     break;
  746.     case ITL_BAD_TRANS:
  747.     break;
  748.  
  749.     }
  750.  
  751.   }
  752. /*
  753. * UpdateRecoveryFile()
  754. *
  755. * This function updates the network recovery file.
  756. */
  757. void UpdateRecoveryFile(char *val)
  758.   {
  759.   SYS_FILE fileNm;
  760.   makeSysName(fileNm, RECOVERY_FILE, &cfg.netArea);
  761.   if (access(fileNm, 0) != 0)
  762.   CallMsg(fileNm, callerId);
  763.   CallMsg(fileNm, val);
  764.  
  765.   }
  766. /*
  767. * RoomRoutable()
  768. *
  769. * Is this room routable?
  770. */
  771. char RoomRoutable(RoomSearch *data)
  772.   {
  773.   if( netDebug && cfg.BoolFlags.debug )
  774.     {
  775.     splitF(netLog, "label Room(%s)  ", data->Room);     /* this is the target */
  776.     splitF(netLog, "char  virtual(%x)",data->virtual);  /* is virtual? */
  777.     splitF(netLog, "int   room(%d)",   data->room);     /* room slot */
  778.     splitF(netLog, "int   index(%d)",  data->index);
  779.     splitF(netLog, "char  reason(%x)", data->reason);
  780.     };
  781.   if (!PosId)
  782.     {
  783.     if( netDebug )splitF(netLog, "-No Password.-");
  784.     data->reason = NO_PWD;
  785.     return FALSE;
  786.  
  787.     }
  788.   if (callSlot == ERROR)
  789.     {
  790.     if( netDebug )splitF(netLog, "-Not sharing.-");
  791.     data->reason = NOT_SHARING;
  792.     return FALSE;
  793.  
  794.     }
  795.   data->reason = NO_ROOM;
  796.   data->virtual = FALSE;
  797.   EachSharedRoom(thisNet, IsRoomRoutable, VirtRoomRoutable, data);
  798.   return (char)(data->reason == FOUND);
  799.  
  800.   }
  801. /*
  802. * IsRoomRoutable()
  803. *
  804. * This function checks to see if the given shared room matches with the
  805. * argument presented in the void pointer parameter.
  806. */
  807. int IsRoomRoutable(SharedRoom *room, int system, int index, int roomslot,
  808. void *d)
  809.   {
  810.   RoomSearch *arg;
  811.   arg = d;
  812.   if (strCmpU(roomTab[roomslot].rtname, arg->Room) == SAMESTRING)
  813.     {
  814.     if (roomTab[roomslot].rtflags.SHARED == 0)
  815.     arg->reason = NOT_SHARING;
  816.     else
  817.     arg->reason = FOUND;
  818.     arg->room = roomslot;
  819.     arg->index = index;
  820.     return ERROR;   /* stop searching */
  821.  
  822.     }
  823.   return TRUE;
  824.  
  825.   }
  826. /*
  827. * netMultiSend()
  828. *
  829. * This function will send requested files via the net.
  830. */
  831. void netMultiSend(DirEntry *fn)
  832.   {
  833.   long Sectors;
  834.   if (!gotCarrier()) return ;
  835.   strCat(msgBuf.mbtext, fn->unambig);
  836.   strCat(msgBuf.mbtext, " ");
  837.   Sectors     = ((fn->FileSize + 127) / SECTSIZE);
  838.   if (ITL_Send(STARTUP))
  839.     {
  840.     mTrPrintf("%s", fn->unambig);
  841.     mTrPrintf("%ld", Sectors);
  842.     ITL_Send(FINISH);
  843.  
  844.     }
  845.   SendHostFile(fn->unambig);
  846.  
  847.   }
  848. /*
  849. * RecoverNetwork()
  850. *
  851. * This function is called during system startup.  If a disaster hit during
  852. * a network session, this will try to recover messages already transferred
  853. * from files left in the network directory.
  854. */
  855. void RecoverNetwork()
  856.   {
  857.   SYS_FILE fileNm;
  858.   char line[50];
  859.   label temp;
  860.   int rover;
  861.   FILE *fd;
  862.   RoomSearch arg;
  863.   extern char inNet;
  864.   makeSysName(fileNm, RECOVERY_FILE, &cfg.netArea);
  865.   if ((fd = safeopen(fileNm, READ_TEXT)) == NULL)
  866.   return;   /* normal */
  867.   inNet = NORMAL_NET;
  868.   SpecialMessage("Network Cleanup");
  869.   if (GetAString(line, sizeof line, fd) != NULL)
  870.     {
  871.     if (searchNet(line, &netBuf) != ERROR)
  872.       {
  873.       PosId = TRUE;
  874.       while (GetAString(line, sizeof line, fd) != NULL)
  875.         {
  876.         if (strncmp(line, FAST_TRANS_FILE, strLen(FAST_TRANS_FILE))
  877.         == SAMESTRING)
  878.         RecoverMassTransfer(line);
  879.         else
  880.           {
  881.           strCpy(arg.Room, line);
  882.           if (RoomRoutable(&arg) && !arg.virtual)
  883.             {
  884.             printf("%s\n", line);
  885.             ReadNetRoomFile(arg.index, NULL);
  886.  
  887.             }
  888.  
  889.           }
  890.  
  891.         }
  892.       readNegMail(FALSE);
  893.       AddNetMsgs("tempmail.$$$", inMail, 2, MAILROOM, TRUE);
  894.       for (rover = 0; ; rover++)
  895.         {
  896.         sPrintf(temp, "rmail.%d", rover);
  897.         if (AddNetMsgs(temp, inRouteMail, 2, MAILROOM, TRUE) == ERROR)
  898.         break;
  899.  
  900.         }
  901.  
  902.       }
  903.  
  904.     }
  905.   fclose(fd);
  906.   unlink(fileNm);
  907.   inNet = NON_NET;
  908.  
  909.   }
  910.